home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Palettes / MiscSwapKitPalette / MiscSwapKit.subproj / MiscSwapView_ByObject.m < prev    next >
Encoding:
Text File  |  1995-04-12  |  6.7 KB  |  246 lines

  1. /* MiscSwapView_ByObject.m                 
  2.  *
  3.  * This is a MiscSwapView category. It can handle swapping of different 
  4.  * contentViews (controlled by MiscSwapContentsController's) into ourself by
  5.  * comparing trigger objects or tags (trigger tags and controller tags). 
  6.  * More in depth information can be found here in the source-code.
  7.  *
  8.  * Written by:         Thomas Engel
  9.  * Created:            24.01.1994 (Copyleft)
  10.  * Last modified:     25.09.1994
  11.  * Copyright (C) 1995 Thomas Engel
  12.  */
  13.  
  14. #import <misckit/MiscSwapView.h>
  15. #import <misckit/MiscSwapContentsController.h>
  16.  
  17. @implementation MiscSwapView(ByObject)
  18.  
  19.  
  20. - trigger
  21. {
  22.     return trigger;
  23. }
  24.  
  25. - swapContentView:sender
  26. {    
  27.     // This is the method that has to be triggered by each trigger for a nice
  28.     // swap. It incorporates the delegate and the new&previous viewCtrl.
  29.     // Our delegate gets informed before the viewControllers are.
  30.     // The new controller will get willSwapIn which should cause a revert or
  31.     // any other method causing the contoller to update/init its view. It's
  32.     // the last chance before it will be displayed.
  33.     // We could check wether the controller has really changed or not but
  34.     // this might cause a problem when using a inspector because the same
  35.     // inspector might show different data. 
  36.     // Maybe we could and a switch here...right now I'll leave it this way.
  37.     // It should work fine.
  38.     // Be sure that whenever you send the message you really have some changes
  39.     // to show. Otherwise it might be not that perfect. 
  40.     //
  41.     // Anyway. The same view will never swap in twice! SwapView take care of
  42.     // that inside setContentView. So you don't have the overhead of a doubled
  43.     // drawing time.
  44.     
  45.     id    oldController;
  46.     
  47.     trigger = sender;
  48.  
  49.     if( [delegate respondsTo:@selector(viewWillSwap:)] )
  50.         [delegate viewWillSwap:self];
  51.  
  52.     oldController = currentController;
  53.     currentController = [self findControllerForTrigger: sender];
  54.  
  55.     [oldController willSwapOut];
  56.     [currentController willSwapIn];
  57.  
  58.     [self setContentView:[currentController view]];
  59.     
  60.     if( [delegate respondsTo:@selector(viewDidSwap:)] )
  61.         [delegate viewDidSwap:self];
  62.  
  63.     [oldController didSwapOut];
  64.     [currentController didSwapIn];
  65.     
  66.     return self;
  67. }
  68.  
  69. - addController:sender
  70. {
  71.     // Adding a viewController has to ensure that there is only one controller
  72.     // for one trigger. The controller added last will be the only known
  73.     // controller after adding has finished!
  74.     // To find interferring controllers we use our findController method.
  75.     // This needs the trigger to check and the right tagComparison setting.
  76.     // If you change the tagComparison setting later the results might not be
  77.     // correct!
  78.     // You are now allowed to add a controller that does not have a trigger
  79.     // since you can rely totally on tag comparisons. A controller with a
  80.     // trigger of nil will for sure not match any other trigger, but could
  81.     // match by tag.
  82.     
  83.     // Since I changed findController to findControllerForTrigger:, you don't
  84.     // have to save the trigger then restore it.    
  85. //    id    oldTrigger;
  86.     id    oldController;
  87.     
  88. //    oldTrigger = trigger;
  89. //    trigger = [sender trigger];
  90.     
  91.     // If there already is someone...remove him.!
  92.  
  93.     // Also do not want the same controller registering more than once. The
  94.     // old way, if a controller changed it's trigger, it would get by
  95.     // findControllerForTrigger: and would be added again.
  96.     [self removeController: sender];
  97.     
  98.     oldController = [self findControllerForTrigger: [sender trigger] ];
  99.     if( oldController ) [self removeController:oldController];
  100.     
  101.     [controllers addObject:sender];
  102.     
  103. //    trigger = oldTrigger;
  104.  
  105.     return self;
  106. }
  107.  
  108. - removeController:sender
  109. {
  110.     // Here we remove  aViewController from the subviewControllers list.
  111.      // ATTENTION: This does not cause the view to disappear when it is the
  112.      // current swapView contents!
  113.  
  114.     [controllers removeObject:sender];
  115.     return self;
  116. }
  117.  
  118. - removeAllControllers
  119. {
  120.     [controllers empty];
  121.     return self;
  122. }
  123.  
  124. - controllers
  125. {
  126.     return controllers;
  127. }
  128.  
  129. - contentsController
  130. {
  131.     return currentController;
  132. }
  133.  
  134. - setTagComparison:(BOOL)flag
  135. {
  136.     // Should we compare the tags first...and then the objects ?
  137.     
  138.     tagComparison = flag;
  139.     return self;
  140. }
  141.  
  142. - (BOOL)doesTagComparison
  143. {
  144.     return tagComparison;
  145. }
  146.  
  147. - findControllerForTrigger: aTrigger
  148. {
  149.      // This is the basic comparison center. Subclasses of this class should
  150.     // implement only the new findControllerByTag(Object) methods and leave
  151.     // this method untouched. Sometime there is a way of finding a more
  152.     // 'useable' trigger even inside the swapAction method.
  153.     // Using this method from addController: to see if there is already a 
  154.     // a controller for that trigger only works when using triggers as the
  155.     // comparison. It does not for tags, since we don't care if someone
  156.     // registers all the controllers for the same tag.. 
  157.     
  158.     id    newController;
  159.  
  160.     newController = nil;    
  161.     
  162.     // Used to also check that trigger responded to tag, but that did not
  163.     // work when the trigger was nil and we wanted a comparison by tag only.
  164.     if( [self doesTagComparison] )
  165.     newController = [self findControllerByTag:[aTrigger tag]];
  166.     if( !newController ) newController = [self findControllerByObject: aTrigger];
  167.  
  168.     return newController;
  169. }
  170.  
  171. - findControllerByTag:(int)aTag
  172. {
  173.     // Here we try to find the right controller by comparing the tags. 
  174.     // Really simple. Well...the trigger has to have a tag different from
  175.     // zero.
  176.     
  177.     id        aViewController;
  178.     int        i;
  179.             
  180.     if( aTag == 0 ) return nil;
  181.     
  182.     aViewController = nil;    
  183.     
  184.     // Ok now lets find out what viewController refers to this tag.
  185.     
  186.     for( i=0; i<[controllers count]; i++ )
  187.     {
  188.         if( aTag == [[controllers objectAt:i] triggerTag] )
  189.         {
  190.             aViewController = [controllers objectAt:i];
  191.             break;
  192.         };
  193.     }
  194.     return aViewController;
  195. }
  196.  
  197. - findControllerByObject:aTrigger
  198. {
  199.     // Here we simple compare the objects. They have to be the SAME...not only
  200.     // similar!!!
  201.     
  202.     id        aViewController;
  203.     int        i;
  204.     
  205.     aViewController = nil;    
  206.     
  207.     // Now that we allow nil triggers we must check for them.
  208.     if (aTrigger == nil)
  209.         return nil;
  210.         
  211.     for( i=0; i<[controllers count]; i++ )
  212.     {
  213.         if( aTrigger == [[controllers objectAt:i] trigger] )
  214.         {
  215.             aViewController = [controllers objectAt:i];
  216.             break;
  217.         };
  218.     }
  219.     return aViewController;
  220. }
  221.  
  222. @end
  223.  
  224. /*
  225.  * History: 24.02.94 Made it a MiscswapView Category.
  226.  *
  227.  *            24.01.94 Made it a subclass of MiscSwapView
  228.  *
  229.  *            08.01.94 Switched to tagComparison for better reading.
  230.  *                     choosesByTagFirst was not that nice.
  231.  *
  232.  *            21.12.93 Code transferred from the old swapPopManager and
  233.  *                     some viewController methods added plus the trigger object
  234.  *                     which now stores the object triggering our swap.
  235.  *
  236.  *            20.12.93 Enlightened the controller to check the tags if they are
  237.  *                     set. This helps to localize apps.
  238.  *
  239.  *            04.12.93 Added a delegate to this class the enable better 
  240.  *                     command-key handling.
  241.  *
  242.  *            04.11.93 First steps to a general-purpose swapPopManager.
  243.  *
  244.  *
  245.  * Bugs: - I'm not sure about what to free....
  246.  */